package com.example.config;

import com.example.filter.JwtAuthenticationTokenFilter;
import com.example.handler.AccessDeniedhandlerImpl;
import com.example.handler.AuthenticationEntryPointImpl;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.authentication.AuthenticationManager;
import org.springframework.security.config.annotation.method.configuration.EnableGlobalMethodSecurity;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
import org.springframework.security.config.http.SessionCreationPolicy;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter;

/*
 *  @author 雨安
 *  类名： SecurityConfig
 *  创建时间：2024/3/18
 */
@Configuration
@EnableGlobalMethodSecurity(prePostEnabled = true) //开启次注解可以使用@PreAuthonrize注解
public class SecurityConfig extends WebSecurityConfigurerAdapter {

    //创建BCryptPasswordEncoder注入容器
    @Bean
    public PasswordEncoder passwordEncoder(){
        return new BCryptPasswordEncoder();
    }

    @Autowired
    private JwtAuthenticationTokenFilter jwtAuthenticationTokenFilter;

    //认证失败 登录401
    @Autowired
    private AuthenticationEntryPointImpl authenticationEntryPoint;

    //授权失败  403无权限
    @Autowired
    private AccessDeniedhandlerImpl accessDeniedhandler;


    //重写此方法进行配置
    @Override
    protected void configure(HttpSecurity http) throws Exception {
        //登录配置
/*        http
                //关闭csrf
                .csrf().disable()
                //不通过session 获取 SecurityContext
                .sessionManagement().sessionCreationPolicy(SessionCreationPolicy.STATELESS)
                .and()
                //配置请求,请求认证配置
                .authorizeRequests()
                //登录接口 允许匿名访问
                .antMatchers("/user/login").anonymous()
                //除上面外的所有请求全部需要鉴权认证
                .anyRequest().authenticated();*/

        //认证配置
        http
                .csrf().disable() //关闭csrf
        /**
         * Spring Security提供的一个枚举值，表示无状态会话策略。
         * 通过配置为STATELESS，可以确保每个请求都是独立的，不依赖于之前的请求状态，适用于无状态的应用程序设计。
         */
                .sessionManagement().sessionCreationPolicy(SessionCreationPolicy.STATELESS)
                .and()
                //配置请求,请求认证配置
                .authorizeRequests()
                //无论是否登录都可以进行访问
                .antMatchers("/com/yuan/hello").permitAll()
                //.anonymous();匿名访问,未登录才可以访问,登录了则不能访问
                .antMatchers("/user/login").anonymous()
                //.anyRequest()表示其他的任意请求,任意用户认证之后都可以访问
                .anyRequest().authenticated();

        //配置过滤器添加  在什么之前 参数一：自定义的过滤器  参数二：他的字节码类
        http.addFilterBefore(jwtAuthenticationTokenFilter, UsernamePasswordAuthenticationFilter.class);
        //添加异常处理器 认证失败处理器
        http.exceptionHandling().authenticationEntryPoint(authenticationEntryPoint)
        .accessDeniedHandler(accessDeniedhandler);//添加无权限的处理器
        //配置跨域 允许跨域
        http.cors();
    }

    @Bean
    @Override
    public AuthenticationManager authenticationManagerBean() throws Exception {
        return super.authenticationManagerBean();
    }



}
